package com.woniu.service.impl;

import com.woniu.HisHospitalizationApi.HisHospitalRecordsApi;
import com.woniu.api.*;
import com.woniu.config.AppConfig;
import com.woniu.dto.*;
import com.woniu.exception.OutpatientException;
import com.woniu.hisoutpatientservicefacade.dto.LoginDto;
import com.woniu.hisoutpatientservicefacade.dto.QueryMedicalRecordParam;
import com.woniu.hisoutpatientservicefacade.dto.ViewInspectionResultsDto;
import com.woniu.hisoutpatientservicefacade.param.*;
import com.woniu.hisoutpatientservicefacade.param.LoginParam;
import com.woniu.param.*;
import com.woniu.service.OutpatientServiceService;
import com.woniu.util.CopyBeanUtil;
import com.woniu.util.Result;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

@Service
public class OutpatientServiceServiceImpl implements OutpatientServiceService {

    @Resource
    private RabbitTemplate rabbitTemplate;

    @Resource
    private RedissonClient redissonClient;

    //患者
    @Resource
    private HisPatientQueryApi patientQueryApi;
    @Resource
    private HisRegisterQueryApi registerQueryApi;
    @Resource
    private HisCaseQueryApi caseQueryApi;
    @Resource
    private HisPrescriptionQueryApi prescriptionQueryApi;

    //检查
    @Resource
    private HisCheckPriceAPI checkPriceAPI;
    @Resource
    private HisCheckAPI checkAPI;
    @Resource
    private HisUroscopyAPI uroscopyAPI;
    @Resource
    private HisImageAPI imageAPI;
    @Resource
    private HisBloodAPI bloodAPI;

    //医护
    @Resource
    private HisSchedulingAPI schedulingAPI;
    @Resource
    private HisOfficeAPI officeAPI;
    @Resource
    private HisStaffAPI staffAPI;

    //药房
    @Resource
    private StockApi stockApi;

    //缴费
    @Resource
    private PayApi payApi;

    //住院服务
    @Resource
    private HisHospitalRecordsApi hospitalRecordsApi;

    //挂号前登录
    @Override
    public LoginDto login(LoginParam param) {

        //添加就诊人
        RegistratPatientParam patientParam = new RegistratPatientParam();
        BeanUtils.copyProperties(param, patientParam);
        Result<HisPatientDto> patientDtoResult = patientQueryApi.registrationOperation(patientParam);

        //查询患者挂号记录
        HisPatientDto patientDto = patientDtoResult.getData();
        PastRegistrationParam pastRegistrationParam = new PastRegistrationParam();
        pastRegistrationParam.setPatientId(patientDto.getPatientId());
        Result<PageDTO<HisRegisterDto>> pageDtoResult = registerQueryApi.pastRegistration(pastRegistrationParam);

        LoginDto<HisPatientDto, PageDTO> loginDto = new LoginDto<>();
        loginDto.setPageDto(pageDtoResult.getData());
        loginDto.setPatientDto(patientDto);

        return loginDto;
    }

    //查询所有科室
    @Override
    public Result queryOffice() {
        return officeAPI.queryOffice(new QueryOfficeParam());
    }

    //查询医生详情
    @Override
    public Result queryDoctor(Integer doctorId) {
        QueryStaffParam queryStaffParam = new QueryStaffParam();
        QueryCriteriaStaffParam queryCriteriaStaffParam = new QueryCriteriaStaffParam();
        queryCriteriaStaffParam.setStaffId(doctorId);
        queryStaffParam.setQueryCriteriaStaffParam(queryCriteriaStaffParam);
        return staffAPI.queryStaff(queryStaffParam);
    }

    //点击时间段预约
    @Override
    public Result register(RegisterParam param) {
        RLock rLock = redissonClient.getLock("register");
        boolean tryLock = rLock.tryLock();
        if (tryLock) {
//            schedulingAPI.changeAppointmentNumber()
        }

        return null;
    }


    //支付挂号费(创建订单)
    @Override
    public Result payment(Integer registerId) {
        //创建挂号订单
//        AddHisRegisterParam addHisRegisterParam = new AddHisRegisterParam();
//        addHisRegisterParam
//        registerQueryApi.newRegistration(addHisRegisterParam);
//        rabbitTemplate.convertAndSend(AppConfig.EXCHANGE_NAME, AppConfig.RK_NAME, );
        return null;
    }

    //支付回调
    @Override
    public Result paymentCallback() {
        return null;
    }

    //叫号查询患者队列
    @Override
    public Result queryPatientCohort(QueryPatientCohortParam param) {
        return null;
    }

    //过号
    @Override
    public Result skipPatient(Integer patientId) {
        return null;
    }

    //显示屏查询
    @Override
    public Result queryOfficePatientCohort(Integer officeId) {
        return null;
    }

    //病历查询
    @Override
    public Result queryMedicalRecord(QueryMedicalRecordParam param) {

        //查询患者表，获取id
        ListHisPatientParam listHisPatientParam = new ListHisPatientParam();
        listHisPatientParam.setPatientName(param.getPatientName());
//        listHisPatientParam.
        Result<PageDTO<HisPatientDto>> pageDTOResult = patientQueryApi.queryPatientInformation(listHisPatientParam);

        //查询病历
        ListHisCaseParam caseParam = new ListHisCaseParam();
        caseParam.setPageParam(param.getPageParam());
        List<HisPatientDto> list = pageDTOResult.getData().getList();
        caseParam.setPatientId(list.get(0).getPatientId());

        return caseQueryApi.queryMedicalRecords(caseParam);
    }

    //生成病历
    @Override
    public Result generateMedicalRecord(GenerateMedicalRecordParam param) {

        //根据id查询挂号信息
        ListHisRegisterParam listHisRegisterParam = new ListHisRegisterParam();
        listHisRegisterParam.setRegisterId(param.getRegisterId());
        Result<PageDTO<HisRegisterDto>> registerMessage = registerQueryApi.registerMessage(listHisRegisterParam);
        HisRegisterDto registerDto = registerMessage.getData().getList().get(0);

        //根据id查询患者信息
        ListHisPatientParam listHisPatientParam = new ListHisPatientParam();
        listHisPatientParam.setPatientId(registerDto.getPatientId());
        Result<PageDTO<HisPatientDto>> pageDTOResult = patientQueryApi.queryPatientInformation(listHisPatientParam);
        HisPatientDto hisPatientDto = pageDTOResult.getData().getList().get(0);

        //生成病历
        AddHisCaseParam caseParam = new AddHisCaseParam();
        BeanUtils.copyProperties(registerDto, caseParam);
        BeanUtils.copyProperties(hisPatientDto, caseParam);

        return caseQueryApi.generateMedicalRecords(caseParam);
    }

    //查看病历
    @Override
    public Result viewMedicalRecord(Integer caseId) {
        ListHisCaseParam hisCaseParam = new ListHisCaseParam();
        hisCaseParam.setCaseId(caseId);

        return caseQueryApi.queryMedicalRecords(hisCaseParam);
    }

    //查看检查价格项目
    @Override
    public Result viewInspectionItems() {
        return checkPriceAPI.queryCheckPrice(new QueryCheckPriceParam());
    }

    //生成检查单
    @Override
    public Result generateChecklist(GenerateChecklistParam param) {

        //查询检查价格项目
        QueryCheckPriceParam priceParam = new QueryCheckPriceParam();
        QueryCriteriaParam criteriaParam = new QueryCriteriaParam();
        ArrayList<CheckPriceDto> list = new ArrayList<>();

        for (Integer id : param.getCheckPriceIds()) {
            criteriaParam.setCheckPriceId(id);
            priceParam.setQueryCriteriaParam(criteriaParam);
            Result<CheckPriceListDto> dtoResult = checkPriceAPI.queryCheckPrice(priceParam);
            list.add(dtoResult.getData().getPageDto().getList().get(0));
        }



        CreateOrModifyCheckParam checkParam = new CreateOrModifyCheckParam();
        List<CheckParam> checkParamList = CopyBeanUtil.copyBean(list, CheckParam.class);
        for (CheckParam c : checkParamList) {
            c.setPatientId(param.getPatientId());
            c.setPatientName(param.getPatientName());
        }
        checkParam.setCheckParamList(checkParamList);
        return checkAPI.createOrModifyCheck(checkParam);
    }

    //查看检查结果
    @Override
    public ViewInspectionResultsDto viewInspectionResults(ViewInspectionResultsParam param) {

        ViewInspectionResultsDto dto = new ViewInspectionResultsDto();
        List<Object> list = new ArrayList<>();

        //查询三个表
        QueryBloodParam bloodParam = new QueryBloodParam();
        BeanUtils.copyProperties(param, bloodParam);
        Result<QueryBloodDto> bloodDtoResult = bloodAPI.queryBlood(bloodParam);
        list.add(bloodDtoResult.getData());

        QueryUroscopyParam queryUroscopyParam = new QueryUroscopyParam();
        BeanUtils.copyProperties(param, queryUroscopyParam);
        Result<QueryUroscopyDto> uroscopyDtoResult = uroscopyAPI.queryUroscopy(queryUroscopyParam);
        list.add(uroscopyDtoResult.getData());

        QueryImageParam queryImageParam = new QueryImageParam();
        BeanUtils.copyProperties(param, queryImageParam);
        Result<QueryImageDto> imageDtoResult = imageAPI.queryImage(queryImageParam);
        list.add(imageDtoResult.getData());

        dto.setInspectionResultList(list);
        return dto;
    }

    //根据名称查询药品
    @Override
    public Result queryMedicineName(String medicineName) {
        return null;
    }

    //生成或修改药品单
    @Override
    public Result generateDrugOrder(GenerateDrugOrderParam param) {
        //删除原有用药单
        DeleteMedicationParam deleteMedicationParam = new DeleteMedicationParam();
        BeanUtils.copyProperties(param, deleteMedicationParam);
        Result<Boolean> booleanResult = prescriptionQueryApi.deleteByIdMedication(deleteMedicationParam);

        if (booleanResult.getData()) {
            //新增
            AddByIdHisPrescriptionParam add = new AddByIdHisPrescriptionParam();
            List<AddHisPrescriptionParam> list = CopyBeanUtil.copyBean(param.getPrescriptionList(), AddHisPrescriptionParam.class);

            add.setList(list);
            add.setCareId(param.getCareId());
            add.setOrderFormId(param.getOrderFormId());
            return prescriptionQueryApi.newDrugs(add);
        }else {
            throw new OutpatientException(1601, "删除失败");
        }
    }

    //查询药品单
    @Override
    public Result queryDrugOrder(Integer careId) {
        ListHisPrescriptionParam prescriptionParam = new ListHisPrescriptionParam();
        prescriptionParam.setCareId(careId);
        return prescriptionQueryApi.queryMedication(prescriptionParam);
    }

    //药品单收费
    @Override
    public Result tollDrugOrder(Integer careId) {

        return null;
    }

    //药品单收费回调
    @Override
    public Result tollDrugOrderCallback() {
        return null;
    }

    //取药
    @Override
    public Result takeMedicine(Integer careId) {
        //查询用药单
        ListHisPrescriptionParam listHisPrescriptionParam = new ListHisPrescriptionParam();
        listHisPrescriptionParam.setCareId(careId);
        Result<PageDTO<HisPrescriptionDto>> medication = prescriptionQueryApi.queryMedication(listHisPrescriptionParam);
        List<HisPrescriptionDto> list = medication.getData().getList();

        //修改库存
        StockParam stockParam = new StockParam();
//        for (HisPrescriptionDto prescriptionDto : list) {
//            QueryPageParam queryPageParam = new QueryPageParam();
//            QueryStockParam queryStockParam = new QueryStockParam();
//            queryStockParam.set
//            queryPageParam.setQueryStockParam();
//            stockApi.getStock()
//            stockParam.setMedicineId(prescriptionDto.getMedicineId());
//            stockParam.
//        }
//        stockApi.updateStock()

        //修改用药单领药状态
        ModifyHisPrescriptionParam prescriptionParam = new ModifyHisPrescriptionParam();
        prescriptionParam.setCareId(careId);

        return prescriptionQueryApi.receivingMedicine(prescriptionParam);
    }

    //住院申请单
    @Override
    public Result applyForHospitalization(PatientDetailsParam param) {
        //补充患者信息
        ModifyHisPatientParam modifyHisPatientParam = new ModifyHisPatientParam();
        BeanUtils.copyProperties(param, modifyHisPatientParam);
        Result<HisPatientDto> patientDtoResult = patientQueryApi.modifyPatientInformation(modifyHisPatientParam);

        //患者住院
        HisHospitalRecordsAddParam recordsAddParam = new HisHospitalRecordsAddParam();
        BeanUtils.copyProperties(patientDtoResult.getData(), recordsAddParam);
        return hospitalRecordsApi.addHisHospitalRecords(recordsAddParam);
    }
}
